<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二叉树层序遍历可视化</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
        }
        .hero {
            background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-radius: 0.5rem;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .highlight {
            position: relative;
        }
        .highlight::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 40%;
            background-color: rgba(59, 130, 246, 0.2);
            z-index: -1;
            transform: skewY(-1deg);
        }
        .tree-node {
            display: inline-block;
            width: 2.5rem;
            height: 2.5rem;
            line-height: 2.5rem;
            text-align: center;
            background-color: #3b82f6;
            color: white;
            border-radius: 50%;
            margin: 0.5rem;
            font-weight: 600;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        }
        .tree-level {
            display: flex;
            justify-content: center;
            margin: 1rem 0;
        }
        .tree-arrow {
            color: #94a3b8;
            text-align: center;
            font-size: 1.2rem;
        }
    </style>
</head>
<body class="min-h-screen">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6 font-serif tracking-tight">二叉树层序遍历</h1>
            <p class="text-xl md:text-2xl opacity-90 mb-8 max-w-3xl mx-auto">探索BFS算法在二叉树遍历中的应用</p>
            <div class="flex justify-center space-x-4">
                <a href="#concept" class="px-6 py-3 bg-white text-blue-600 font-semibold rounded-full hover:bg-opacity-90 transition duration-300">核心概念</a>
                <a href="#code" class="px-6 py-3 bg-opacity-20 border border-white font-semibold rounded-full hover:bg-opacity-30 transition duration-300">代码实现</a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto px-4 py-12 max-w-4xl">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg text-slate-700 leading-relaxed mb-6">
                要打印出二叉树中每一层的节点，我们可以使用<strong class="highlight font-semibold">层序遍历</strong>（Level Order Traversal）方法。这种方法通常使用<strong class="highlight font-semibold">广度优先搜索</strong>（BFS）的思路，通过一个队列（<code>Queue</code>）来实现。队列用于保存每一层的节点，遍历时依次从队列中取出节点并将其子节点加入队列，这样我们就可以按层顺序遍历整棵树。
            </p>
        </section>

        <!-- Visualization -->
        <section class="mb-16">
            <h2 id="concept" class="text-3xl font-bold mb-8 text-center font-serif">二叉树层序遍历可视化</h2>
            
            <div class="bg-white rounded-xl p-6 mb-10 card">
                <div class="flex justify-center mb-8">
                    <div class="tree-level">
                        <div class="tree-node" style="background-color: #1d4ed8;">1</div>
                    </div>
                </div>
                <div class="tree-arrow">
                    <i class="fas fa-arrow-down"></i>
                </div>
                <div class="flex justify-center mb-8">
                    <div class="tree-level">
                        <div class="tree-node">2</div>
                        <div class="tree-node">3</div>
                    </div>
                </div>
                <div class="tree-arrow">
                    <i class="fas fa-arrow-down"></i>
                </div>
                <div class="flex justify-center">
                    <div class="tree-level">
                        <div class="tree-node">4</div>
                        <div class="tree-node">5</div>
                        <div class="tree-node">6</div>
                        <div class="tree-node">7</div>
                    </div>
                </div>
            </div>

            <div class="mermaid">
                graph TD
                    A((1)) --> B((2))
                    A --> C((3))
                    B --> D((4))
                    B --> E((5))
                    C --> F((6))
                    C --> G((7))
            </div>
        </section>

        <!-- Method Overview -->
        <section class="mb-16">
            <div class="bg-white rounded-xl p-8 card">
                <h2 class="text-2xl font-bold mb-6 flex items-center">
                    <i class="fas fa-project-diagram mr-3 text-blue-500"></i>
                    <span>方法概述</span>
                </h2>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
                            <span class="font-bold">1</span>
                        </div>
                        <div>
                            <h3 class="font-semibold text-lg mb-1">初始化队列</h3>
                            <p class="text-slate-600">将根节点加入队列。</p>
                        </div>
                    </div>
                    <div class="flex items-start">
                        <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
                            <span class="font-bold">2</span>
                        </div>
                        <div>
                            <h3 class="font-semibold text-lg mb-1">层序遍历</h3>
                            <p class="text-slate-600">
                                使用一个循环遍历队列，直到队列为空。
                                <ul class="list-disc pl-5 mt-2 space-y-1 text-slate-600">
                                    <li>对于队列中的每个节点，打印它的值</li>
                                    <li>将节点的左右子节点（如果有的话）加入队列</li>
                                </ul>
                            </p>
                        </div>
                    </div>
                    <div class="flex items-start">
                        <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
                            <span class="font-bold">3</span>
                        </div>
                        <div>
                            <h3 class="font-semibold text-lg mb-1">区分层次</h3>
                            <p class="text-slate-600">为了区分不同层次，可以在每一层的开始记录当前队列的长度（即当前层的节点数），然后在每层遍历开始时打印换行或其他层次信息。</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Code Example -->
        <section class="mb-16" id="code">
            <h2 class="text-3xl font-bold mb-6 text-center font-serif">代码实现</h2>
            <div class="code-block p-6 mb-8 rounded-lg">
                <div class="flex items-center text-slate-400 mb-4">
                    <div class="h-3 w-3 rounded-full bg-red-500 mr-2"></div>
                    <div class="h-3 w-3 rounded-full bg-yellow-500 mr-2"></div>
                    <div class="h-3 w-3 rounded-full bg-green-500 mr-2"></div>
                    <span class="ml-auto text-sm">BinaryTreeDemo.java</span>
                </div>
                <pre class="text-slate-100 overflow-x-auto"><code>import java.util.LinkedList;
import java.util.Queue;

// 定义二叉树节点类
class TreeNode {
    int val;  // 节点值
    TreeNode left;  // 左子节点
    TreeNode right;  // 右子节点

    TreeNode(int val) {
        this.val = val;
    }
}

public class BinaryTreeDemo {

    // 打印二叉树每一层的节点
    public static void printTreeByLevel(TreeNode root) {
        if (root == null) {
            return;  // 如果树为空，直接返回
        }

        Queue&lt;TreeNode&gt; queue = new LinkedList&lt;&gt;();  // 使用队列来实现层序遍历
        queue.offer(root);  // 将根节点加入队列

        while (!queue.isEmpty()) {
            int levelSize = queue.size();  // 获取当前层的节点数量
            for (int i = 0; i &lt; levelSize; i++) {
                TreeNode currentNode = queue.poll();  // 取出队首节点
                System.out.print(currentNode.val + " ");  // 打印当前节点的值

                // 将左右子节点加入队列
                if (currentNode.left != null) {
                    queue.offer(currentNode.left);
                }
                if (currentNode.right != null) {
                    queue.offer(currentNode.right);
                }
            }
            System.out.println();  // 每层遍历结束后换行
        }
    }

    public static void main(String[] args) {
        // 构造一个简单的二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);

        System.out.println("二叉树的层序遍历结果：");
        printTreeByLevel(root);  // 调用方法打印二叉树每一层的节点
    }
}</code></pre>
            </div>

            <div class="bg-white rounded-xl p-8 card">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <i class="fas fa-code mr-3 text-blue-500"></i>
                    <span>代码详解</span>
                </h3>
                <div class="space-y-4">
                    <div>
                        <h4 class="font-semibold text-lg mb-1">TreeNode 类</h4>
                        <p class="text-slate-600">定义了一个简单的二叉树节点类，包含节点值（<code>val</code>）、左子节点（<code>left</code>）、右子节点（<code>right</code>）。</p>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-1">printTreeByLevel 方法</h4>
                        <p class="text-slate-600">
                            <ul class="list-disc pl-5 mt-2 space-y-1">
                                <li>首先判断树是否为空，如果为空则直接返回</li>
                                <li>创建一个队列（<code>Queue</code>）用于存储每一层的节点，初始时将根节点加入队列</li>
                                <li>使用 <code>while</code> 循环遍历队列，直到队列为空为止</li>
                                <li>在每次循环的开始，记录当前队列的长度（<code>levelSize</code>），这表示当前层的节点数</li>
                                <li>遍历当前层的每个节点，打印其值，并将其左右子节点（如果存在）加入队列</li>
                                <li>每层遍历结束后换行</li>
                            </ul>
                        </p>
                    </div>
                    <div>
                        <h4 class="font-semibold text-lg mb-1">main 方法</h4>
                        <p class="text-slate-600">构造一个简单的二叉树，并调用 <code>printTreeByLevel</code> 方法打印每一层的节点</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Output Example -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-center font-serif">示例输出</h2>
            <div class="bg-white rounded-xl p-8 card">
                <div class="code-block p-6 rounded-lg">
                    <div class="flex items-center text-slate-400 mb-4">
                        <div class="h-3 w-3 rounded-full bg-red-500 mr-2"></div>
                        <div class="h-3 w-3 rounded-full bg-yellow-500 mr-2"></div>
                        <div class="h-3 w-3 rounded-full bg-green-500 mr-2"></div>
                        <span class="ml-auto text-sm">Console Output</span>
                    </div>
                    <pre class="text-slate-100 overflow-x-auto"><code>二叉树的层序遍历结果：
1 
2 3 
4 5 6 7</code></pre>
                </div>
                <p class="mt-6 text-slate-600">
                    上述输出展示了给定二叉树的每一层的节点，依次为第一层（根节点）、第二层、第三层。
                </p>
            </div>
        </section>

        <!-- Key Takeaways -->
        <section class="mb-16">
            <div class="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl p-8 card">
                <h2 class="text-2xl font-bold mb-6 flex items-center">
                    <i class="fas fa-lightbulb mr-3 text-yellow-500"></i>
                    <span>核心要点</span>
                </h2>
                <div class="grid md:grid-cols-2 gap-6">
                    <div class="bg-white p-6 rounded-lg">
                        <h3 class="font-semibold text-lg mb-3 text-blue-600">BFS算法</h3>
                        <p class="text-slate-600">层序遍历是广度优先搜索(BFS)在二叉树上的应用，使用队列数据结构实现逐层访问节点。</p>
                    </div>
                    <div class="bg-white p-6 rounded-lg">
                        <h3 class="font-semibold text-lg mb-3 text-blue-600">时间复杂度</h3>
                        <p class="text-slate-600">O(n)，其中n是二叉树的节点数，因为每个节点都会被访问且仅被访问一次。</p>
                    </div>
                    <div class="bg-white p-6 rounded-lg">
                        <h3 class="font-semibold text-lg mb-3 text-blue-600">空间复杂度</h3>
                        <p class="text-slate-600">O(n)，最坏情况下队列中需要保存所有叶子节点，对于完美二叉树约为n/2。</p>
                    </div>
                    <div class="bg-white p-6 rounded-lg">
                        <h3 class="font-semibold text-lg mb-3 text-blue-600">应用场景</h3>
                        <p class="text-slate-600">计算二叉树高度、查找某层节点、序列化二叉树等多种场景都会用到层序遍历。</p>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-slate-900 text-white py-8">
        <div class="container mx-auto px-4 max-w-4xl">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h3 class="text-xl font-bold">技术小馆</h3>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-blue-300 hover:text-white transition duration-300">
                        <i class="fas fa-external-link-alt mr-2"></i>
                        www.yuque.com/jtostring
                    </a>
                </div>
            </div>
            <div class="mt-6 pt-6 border-t border-slate-800 text-center text-slate-400 text-sm">
                &copy; 2023 技术小馆. 保留所有权利.
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'dark',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>